C++ static关键字

在C++中,static关键字有多个作用,具体取决于它是用来修饰全局变量、局部变量、函数还是类的成员。以下是static的一些主要用途:

  1. 修饰全局变量:当static用于全局变量时,它限制了变量的作用域,使得该变量只在定义它的文件内可见。
  2. 修饰局部变量:用于局部变量时,static使得该变量的生命周期延长至程序运行结束,即使函数调用结束,变量的值也不会丢失,并在下次该函数被调用时保持上次的值。
  3. 修饰函数:当static用于函数时,它意味着该函数只能在其定义的文件内部被调用,不可在其他文件中使用。
  4. 修饰类的成员
    • 静态数据成员static可以用来修饰类的数据成员,这意味着无论创建多少对象,类的静态数据成员只有一个副本。
    • 静态成员函数:静态成员函数不与任何对象绑定,它们不能访问类的非静态成员,只能访问静态成员。
      静态成员在类外定义和初始化,以确保只被定义和初始化一次。静态成员函数和变量由于属于类而不是对象,因此可以被多个对象共享。
#include <iostream>

class MyClass {
public:
    static int class_var;  // 类作用域变量
};

int MyClass::class_var = 30;

int main() {
    std::cout << "类变量: " << MyClass::class_var << std::endl;
    return 0;
}

在上述代码示例中,MyClass 类有一个静态成员变量 class_var。这意味着无论创建多少个 MyClass 对象,class_var 只会有一个副本。所有对象共享这个变量,而不是每个对象都有自己的副本。
静态成员变量需要在类外部进行初始化,正如您的代码所示:

int MyClass::class_var = 30;

这行代码设置了 class_var 的初始值为 30。由于 class_var 是静态的,这个值将被所有 MyClass 对象共享。如果其中一个对象更改了 class_var 的值,那么这个新值将反映在所有其他对象中。
静态成员变量通常用于存储类级别的数据,例如,用于跟踪类的所有实例数量或作为配置变量,它们对所有实例都是相同的。
下面是一个使用静态数据成员的简单例子:

#include <iostream>
using namespace std;

class Employee {
public:
    static int count;  // 静态数据成员,用于跟踪创建的Employee对象数量

    // 构造函数
    Employee() {
        // 每创建一个新对象,count就增加1
        count++;
    }
};

// 在类外初始化静态成员变量
int Employee::count = 0;

int main() {
    // 创建Employee对象
    Employee e1;
    Employee e2;
    Employee e3;

    // 输出当前创建的Employee对象数量
    cout << "Total employees: " << Employee::count << endl;

    return 0;
}

运行结果

Total employees: 3

在这个例子中,我们定义了一个 Employee 类,它有一个静态数据成员 count。这个成员变量用来跟踪创建了多少个 Employee 对象。每次创建 Employee 类的新实例时,构造函数都会增加 count 的值。在 main 函数中,我们创建了三个 Employee 对象,然后输出 count 的值,它将显示为 3,因为我们创建了三个对象。
这个例子展示了如何使用静态数据成员来存储与类相关的数据,而不是与特定对象相关的数据。

静态成员函数是类的成员函数,但它不依赖于类的任何对象。它可以直接通过类名调用,而不需要创建类的对象。静态成员函数只能访问类的静态成员变量和其他静态成员函数。
以下是一个静态成员函数的例子:

#include <iostream>
using namespace std;

class MathUtils {
public:
    // 静态成员函数,计算两个数的最大公约数(GCD)
    static int gcd(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
};

int main() {
    // 直接通过类名调用静态成员函数
    cout << "GCD of 20 and 30 is: " << MathUtils::gcd(20, 30) << endl;

    return 0;
}

在这个例子中,MathUtils 类有一个静态成员函数 gcd,它用于计算两个整数的最大公约数。我们可以直接通过类名 MathUtils 调用 gcd 函数,而不需要创建 MathUtils 类的对象。这展示了静态成员函数的特点和如何使用它们。
静态成员函数通常用于实现不依赖于对象状态的功能,例如工具函数或数学计算。